package a1;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.JToggleButton;

public class ColorSelectionRadioButton extends JRadioButton implements FocusListener {
        private Color currentColor;		// the current color this Radio Button holds
        
        private JTextField textField;	// the text field will display the color as a string, 
                                       	// as well as take a string and change the current color
                                  		// to the user-inputted color (this is still TODO)
        private JPanel panel;    		// the panel is a small preview for the selected colour
        private Model m;
        
        /**
         * Required since {@link JRadioButton}s are {@link Serializable}.
         */
        private static final long serialVersionUID = -7792645404576975971L;
        
        /**
         * Constructs a panel set to the passed color.
         * @param initialColor The color the panel should be set to.
         */
        public ColorSelectionRadioButton(Model m, Color initialColor) {
                super();   // common idiom to call super first when extending
                
                this.setLayout(new GridLayout(1,3));
                this.m = m;
                this.currentColor = initialColor;       // set the current color for this panel to the supplied color
                
                // TODO create a formatter so that we can change modes between 
                // RGB: (123, 123, 123) and HEX: #DDDDDD notations based on which 
                // mode the user has selected from the menu bar. Use like:
                // OutputTextForColor(Color color)
                String text = Model.makeText(m.getMode(), this.currentColor);                
                
                this.textField = new JTextField(text);  // set textField to display the currently supplied colour
                this.textField.addFocusListener(this);  // we want the textField to requestFocus for the CSRB if it gains focus
                
                this.panel = new JPanel();
                this.panel.setBackground(initialColor); // set the preiew panel to display currently supplied colour
                this.panel.setPreferredSize(Constants.SMALL_PREVIEW_PREFFERED_SIZE); // fix panel to a small size
                
                this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));  // organizes the textField and panel
                this.setModel(new JToggleButton.ToggleButtonModel());   // adds the logic for a radio button
                
                this.textField.setHorizontalAlignment(JTextField.RIGHT);        // set text to align right
                
                this.add(Box.createHorizontalStrut(Constants.RADIO_BUTTON_GAP)); //create gap for textField
                this.add(textField);    // Add textField        
                this.add(panel); 	    // add preview panel right up against textField
                
                //this.setSize(Constants.CSRB_WIDTH, this.getPreferredSize().height);
                
        }
        
        /**
         * Default Constructor. Sets the default selected color to {@link Color.BLACK}
         */
        public ColorSelectionRadioButton(Model m) {
        	this(m, Color.black);
        }
        
        
        
        /** 
         * Returns the current colour for this radio button.
         * @return the current colour
         */
        public Color getColor() {
                return this.currentColor;
        }
        
        /**
         * Sets the current colour for this radio button to the specified colour.
         * @param color the colour to set this radio button
         */
        public void setColor(Color color) {
                this.currentColor = color;
                this.panel.setBackground(color);
                //this.setText(color);
        }
        
        /** 
         * Sets grayscale color given the current mode
         * @param mode mode to set colour to. See Constants
         * @param color the color we will set the CSRB to
         */
        public void setColor(int mode, Color color) {
            this.currentColor = color;
            this.panel.setBackground(color);
            
            this.setText(Model.makeText(mode, color));
            //this.setText(color);
        }
        
        /**
         * Sets text of the CSRB
         */
        @Override       // TODO Documentation
        public void setText(String text) {
                this.textField.setText(text);
        }
        
        /** 
         * Sets color and text by invoking setColor() and setText()
         * @param color color to set CSRB to
         * @param text text to set CSRB to
         */
        public void setColorAndText(Color color, String text) {
                this.setColor(color);
                this.setText(text);
        }
        
        @Override
        public String getText() {
                //this.textField.getText();
                //System.out.println("getText returns: " + this.textField.getText());
                try {
                        return this.textField.getText();
                } catch (Exception e) {
                        return "";
                }
        }
        
        public boolean parseInput(int mode) {
        	
        	try {
        		Model.parseText(mode, this.textField.getText());
        	} catch (Exception e) {
        		return false;
        	}
        	        	
        	return true;
        }
        /*
        public boolean parseInput() 
    	{
    		Boolean result = true;
    		String input = this.textField.getText();
    		//simple regex to match to sets of up to three numbers for RGB
    		if(input.matches(".?(\\d{1,3}),\\s?(\\d{1,3}),\\s?(\\d{1,3}).?")) 
    		{
    			StringTokenizer tokenizer = new StringTokenizer(input, "(), ");
    			for(;!tokenizer.hasMoreElements();)
    			{
    				int i = Integer.parseInt(tokenizer.nextToken());
    				if (i >= 256 || i < 0)
    					result = false;
    			}
    		}
    		else result = false;
    		
    		/* next step is to add something to parse hex and other inputs, will leave until focus listener is done.
    		if(input.matches("[0-9 a-f A-F]"))
    		{
    			
    		}
    		*//*
    		return result;
    		//... implement algorithm to parse the string here, return false if you cannot parse.
    	} */

        @Override
        public void focusGained(FocusEvent e) {
                // TODO Auto-generated method stub
        	
        	Object source = e.getSource();
        	System.out.println("CSRB gained focus: " + source.getClass()); 
            if (source instanceof JTextField)
            {   // handle events for the textField
            	// ask the View to set this CSRB to selected and display its color
            	this.firePropertyChange(Constants.ASK_FOCUS_EVENT, false, true);
            }
        }

        @Override
        public void focusLost(FocusEvent e) {
        	// if the CSRB loses focus, we must parse it to see if what the user entered was valid
        	// if the user entered something invalid, we return focus to the textField
        	Object source = e.getSource();
        	System.out.println("CSRB lost focus: " + source.getClass());
        	if (source instanceof JTextField) {
        		// parse text
        		JTextField f = (JTextField) source;
        		String text = f.getText();
        		System.out.println("Text for the old textfield is " + text);
        		Color c = Model.parseText(text);
        		if (c == null) {
        			// the color is invalid, let's show an error
        			f.setText("");
        			f.setBackground(Color.pink);
        			f.requestFocusInWindow();
        			this.firePropertyChange(Constants.COLOR_PARSE_ERROR, false, true);
        		} else {
        			// the color is valid, let's continue
        			f.setBackground(Color.white);
        			this.currentColor = c;
                    this.panel.setBackground(c);
                    this.textField.setText(Model.makeText(m.getMode(), c));
        			this.firePropertyChange(Constants.TEXTFIELD_LOST_FOCUS_EVENT, false, true);
        		}
        	}

        }
        
        @Override
        public boolean requestFocusInWindow() {
                /*if (!super.requestFocusInWindow())
                        return false;*/
                return this.textField.requestFocusInWindow();
                
        }     
        /*
        @Override
        public Dimension getSize() {
        	return new Dimension(Constants.CSRB_WIDTH, this.getPreferredSize().height);
        }*/
}